﻿using IrisMembership.DataLayer;
using IrisMembership.DomainClasses;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IrisMembership.ServiceLayer
{
    public class UserService : IUserService
    {
        private readonly IDbSet<User> _users;
        private readonly IIrisDbContext _dbContext;

        public UserService(IIrisDbContext dbcontext)
        {
            _dbContext = dbcontext;
            _users = dbcontext.Set<User>();
        }

        public bool IsExistByUserName(string userName)
        {
            return _users.Any(u => u.UserName == userName);
        }

        public bool IsExistByEmail(string email)
        {
            return _users.Any(u => u.Email == email);
        }

        public async Task<bool> IsExistByUserNameAsync(string userName)
        {
            return await _users.AnyAsync(u => u.UserName == userName);
        }

        public async Task<bool> IsExistByEmailAsync(string email)
        {
            return await _users.AnyAsync(u => u.Email == email);
        }

        public AddUserStatus Add(User user)
        {
            AddUserStatus addUserStatus;

            if (IsExistByUserName(user.UserName))
            {
                addUserStatus = AddUserStatus.DuplicateUserName;
            }
            else if (IsExistByEmail(user.Email))
            {
                addUserStatus = AddUserStatus.DuplicateEmail;
            }
            else
            {
                _users.Add(user);
                addUserStatus = AddUserStatus.Success;
            }

            return addUserStatus;
        }

        public async Task<AddUserStatus> AddAsync(User user)
        {
            AddUserStatus addUserStatus;

            if (await IsExistByUserNameAsync(user.UserName))
            {
                addUserStatus = AddUserStatus.DuplicateUserName;
            }
            else if (await IsExistByEmailAsync(user.Email))
            {
                addUserStatus = AddUserStatus.DuplicateEmail;
            }
            else
            {
                _users.Add(user);
                addUserStatus = AddUserStatus.Success;
            }

            return addUserStatus;
        }

        public bool ValidateUserByEmail(string email, string password)
        {
            return _users.Any(u => u.Email == email && u.Password == password);
        }

        public bool ValdiateUserByUserName(string userName, string password)
        {
            return _users.Any(u => u.UserName == userName && u.Password == password);
        }

        public async Task<bool> ValidateUserByEmailAsync(string email, string password)
        {
            return await _users.AnyAsync(u => u.Email == email && u.Password == password);
        }

        public async Task<bool> ValdiateUserByUserNameAsync(string userName, string password)
        {
            return await _users.AnyAsync(u => u.UserName == userName && u.Password == password);
        }


        public User FindByEmail(string email)
        {
            return _users.SingleOrDefault(u => u.Email == email);
        }

        public async Task<User> FindByEmailAsync(string email)
        {
            return await _users.SingleOrDefaultAsync(u => u.Email == email);
        }


        public IList<User> GetUsersListByRoleId(int roleId)
        {
            throw new NotImplementedException();
        }

        public async Task<IList<User>> GetUsersListByRoleIdAsync(int roleId)
        {
            return await _users.Where(u => u.Roles.Any(r => r.Id == roleId)).ToListAsync();
        }


        public User FindByUserId(int userId)
        {
            return _users.Find(userId);
        }

        public async Task<User> FindByUserIdAsync(int userId)
        {
            return await _users.SingleAsync(u => u.Id == userId);
        }

        public void AddRoleToUser(int userId, ICollection<Role> roles)
        {
            foreach (var role in roles)
            {
                FindByUserId(userId).Roles.Add(role);
            }
        }
    }
}
